#include "nfc_read_card.h"
#include "nfc_ctrl.h"
#include "string.h"
#include "nfc_read_switch.h"
#include "key.h"
#include "ver_comp.h"
typedef struct
{
    Rt_result (*NFC_read_test)(void);
} AppServer_NFCread_Fun;

Rt_result NFCRC_hard_soft(void);
Rt_result NFCRed_swipe(void);
static NFCRC_struct NFCRC_s;

static AppServer_NFCread_Fun NFC_read[NFC_READ_MAX] = 
{
    {NFCRC_hard_soft},
    {NFCCTRL_low_power},
    {NFCRed_swipe}
};

static uint8_t can_com_data[8] = {0x22, 0xF1, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00};      /*can软硬件版本请求*/
static uint8_t can_swipe_data[8] = {0x31, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};    /*can请求刷卡测试*/
/*
 * 函数介绍: NFC读卡器CAN接受回调
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void NFCRC_read_card_cbk(uint16_t id, uint8_t data[])
{
    if ((CAN_REC_ID == id || CAN_SWIPE_ID == id) && OK_SENT_OR_RECEIVED == NFCRC_s.cantx_flag)
    {
        NFCRC_s.cantx_flag = NO_SENT_OR_RECEIVED;           /*清除各阶段CAN发送成功标志*/
        NFCRC_s.canrx_flag = OK_SENT_OR_RECEIVED;           /*写入各阶段CAN接受成功标志*/
		NFCRC_s.canrx.can_id = id;
        memcpy(NFCRC_s.canrx.can_data,data,8); /*填入接受data*/
    }
    else
    {
    }
}

/*
 * 函数介绍: NFC读卡器初始化
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void NFCRC_read_card_init(void)
{
    uint8_t i;
    NFCRC_s.stage = CAN_TEST;/*NFC_读卡器测试阶段*/
    for (i = 0; i < NFC_READ_MAX; i++)
    {
        NFCRC_s.e_sta[i] = TEST_WAIT;
    }
    NFCRC_s.RED_ver_comp = TEST_WAIT;
    NFCRC_s.RC_results = TEST_WAIT;
    NFCRC_s.cantx_flag = NO_SENT_OR_RECEIVED;
    NFCRC_s.canrx_flag = NO_SENT_OR_RECEIVED;
    NFCRC_s.N_flag.NFCRC_send_data_only = false;
    NFCRC_s.N_flag.SWIPE_send_data_only = false;
    NFCRC_s.N_flag.start_keyStableState = false;
    NFCRC_s.N_flag.swipe_stage = SWIPE_MX;
    NFCRC_s.N_flag.swipe_count = 0;
    NFCRC_s.N_flag.key_count = 0;
    NFCRC_s.N_flag.swipe_num = 0;
    NFCRC_s.N_flag.swie_max_delms = 0;
    NFCRC_s.N_flag.swipe_key_num_suc = false;

}

/*
 * 函数介绍: NFC读卡器CAN通讯测试读取软硬件版本号
 * 参数:
 * 返回值: {*}
 * 备注:
 */
Rt_result NFCRC_hard_soft(void)
{
    Rt_result result = TEST_WAIT;
    static uint32_t Record_send_time = 0; /*记录_发送_时间*/
    uint8_t candata[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};     /*can软硬件失败版本号*/
    /*只发送一次读取请求*/
    if (false == NFCRC_s.N_flag.NFCRC_send_data_only)
    {
        NFCRC_s.cantx.can_id = CAN_FUN_ADDR;                                /*填入发送ID*/
        memcpy(NFCRC_s.cantx.can_data, can_com_data, sizeof(can_com_data)); /*填入发送data*/
        NFCRC_s.N_flag.NFCRC_send_data_only = true;
        for (uint8_t i = 0; i < 4; i++)
        {
			RTE_HAL_DELAY(50);
            RTE_CAN_TRANSMIT(NFCRC_s.cantx.can_id,NFCRC_s.cantx.can_data,CAN_LEN);/*CAN发送软硬件版本请求*/
            
        }
        NFCRC_s.cantx_flag = OK_SENT_OR_RECEIVED;   /*发送标志位置位*/
        NFCRC_s.canrx_flag = NO_SENT_OR_RECEIVED;
        Record_send_time = RTE_GET_TIMER();         /*记录发送开始时间*/
    }
    /*CAN接受到回复或者超时进入*/
    else if (OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag || RTE_TIMEOUT_JUDGMENT(Record_send_time, NFCRC_MAX_DELMS))
    {
        /*接受到回复*/
        if (OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag)
        {
            NFCRC_s.RED_ver_comp = NFCCTRL_rtlcd_can_swhd(STATUS_QUALIFIED,NFC_READER_TEST,NFCRC_s.canrx.can_data);
            result = TEST_OK;
        }
        else
        {
            /*超时*/
            NFCRC_s.RED_ver_comp = NFCCTRL_rtlcd_can_swhd(STATUS_UNQUALIFIED,NFC_READER_TEST,candata);
            result = TEST_FAIL;
        }
        NFCRC_s.N_flag.NFCRC_send_data_only = false;
    }
    else
    {
    }
    return result;
}

/**
 * 在LCD上显示NFC刷卡结果
 * 
 * 本函数用于根据NFC读卡器的状态，将刷卡结果展示在LCD屏幕上。
 * 根据是否成功读取到卡片，选择不同的提示信息和结果展示。
 *
 * @param result 刷卡结果，类型为Rt_result，包含了操作成功或失败的详细信息。
 */
void NFCRC_swipe_lcdshow (Rt_result result)
{
    // 检测NFC读卡器是否成功读取了卡片
    //if (READ_CARD == Nfc_get_read())
    //{
        // 成功读取卡片时，在LCD上显示相应的测试信息和结果
        //RTE_UART7_LCD_SHOW(NFC_READER_TEST, CARD_SWIPE_TEST, result);
    //}else{
        // 未成功读取卡片时，在LCD上显示另一套测试信息和结果
        RTE_UART7_LCD_SHOW(NFC_CARD_READER_TEST, CARD_SWIPE_TEST, result);
        RTE_UART7_LCD_SHOW(NFC_CARD_READER_TEST, TEST_RESULT, result);
    //}
    
}

/*
 * 函数介绍: NFC读卡器刷卡测试
 * 参数:
 * 返回值: {*}
 * 备注:也是一个单独测试NFC卡的流程
 */
Rt_result NFCRC_swipe(void)
{
    Rt_result result = TEST_WAIT;
    static uint32_t Record_send_time = 0; /*记录_发送_时间*/
    /*只发送一次读取请求*/
    if (false == NFCRC_s.N_flag.NFCRC_send_data_only)
    {
        NFCRC_s.cantx.can_id = CAN_FUN_ADDR;                                /*填入发送ID*/
        memcpy(NFCRC_s.cantx.can_data,can_swipe_data, sizeof(can_swipe_data)); /*填入发送data*/
        NFCRC_s.N_flag.NFCRC_send_data_only = true;
        if (TEST_CARD == Nfc_get_read())
        {/*单独测试卡的时候需要多发几帧唤醒读卡器*/          
            RTE_CAN_TRANSMIT(NFCRC_s.cantx.can_id,NFCRC_s.cantx.can_data,CAN_LEN);          /*CAN发送软硬件版本请求*/
            RTE_HAL_DELAY(50);
			RTE_CAN_TRANSMIT(NFCRC_s.cantx.can_id,NFCRC_s.cantx.can_data,CAN_LEN);          /*CAN发送软硬件版本请求*/
            RTE_HAL_DELAY(50);
        }
        RTE_CAN_TRANSMIT(NFCRC_s.cantx.can_id,NFCRC_s.cantx.can_data,CAN_LEN);          /*CAN发送软硬件版本请求*/
        NFCRC_s.cantx_flag = OK_SENT_OR_RECEIVED; /*发送标志位置位*/
        NFCRC_s.canrx_flag = NO_SENT_OR_RECEIVED;
        Record_send_time = RTE_GET_TIMER();            /*记录发送开始时间*/
    }
    /*CAN接受到回复或者超时进入*/
    else if (OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag || RTE_TIMEOUT_JUDGMENT(Record_send_time, NFCRC_MAX_DELMS))
    {
        /*接受到回复*/
        if (OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag)
        {
            if (0x01 == NFCRC_s.canrx.can_data[0])
            {
                result = TEST_OK;
            }else{
                result = TEST_FAIL;
            }
        }
        else
        {
            /*超时*/
            result = TEST_FAIL;
        }
        NFCRC_swipe_lcdshow(result);
        NFCRC_s.N_flag.NFCRC_send_data_only = false;
    }
    return result;
}

/*
 * 函数介绍: NFC读卡器按键刷卡检测
 * 参数:
 * 返回值: {*}
 * 备注:也是一个单独测试NFC卡的流程
 */
void NFCRed_key(void)
{
    static uint32_t Record_send_time = 0; /*记录_发送_时间*/
    if ((CARD_TEST == NFCRC_s.stage && KEY_WAIT == NFCRC_s.N_flag.swipe_stage) && \
			(0 == RTE_GPIO_PIN_GET_LEVEL(GPIOA, START1_TEST_I_PA15_Pin) || 0 == RTE_GPIO_PIN_GET_LEVEL(GPIOA, START2_TEST_I_PA9_Pin))/* condition */)
    {
        if (false == NFCRC_s.N_flag.start_keyStableState)
        {                                            // 如果之前按键是稳定的（未按下状态）
            Record_send_time = RTE_GET_TIMER();    // 记录按键按下的开始时间
            NFCRC_s.N_flag.start_keyStableState = true;     // 设置按键状态为不稳定
        }
        else if (RTE_TIMEOUT_JUDGMENT(Record_send_time, DEBOUNCE_TIME_MS))
        {
            /*按键按下，开始一次新的刷卡测试*/
            NFCRC_s.N_flag.swipe_stage = SWIPE_WAIT;
            RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_ACTION_STATE, SWIPE_WAIT);/*显示当前测试状态为等待刷卡*/
            NFCRC_s.N_flag.key_count ++;
            RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_BUTTON_NUM, (uint32_t)NFCRC_s.N_flag.key_count);/*显示当前刷卡按键次数*/
            NFCRC_s.N_flag.start_keyStableState = false;    // 设置按键状态为稳定
        }
    }
    
}


/*
 * 函数介绍: NFC读卡器单独的刷卡测试
 * 参数:
 * 返回值: {*}
 * 备注:也是一个单独测试NFC卡的流程
 */
Rt_result NFCRed_swipe(void)
{
    Rt_result result = TEST_WAIT;
    static uint32_t Record_send_time = 0; /*记录_发送_时间*/
    static uint32_t SWIPE_send_time = 0; /*记录_发送_时间*/

    /*30s，5次刷卡结果判断成功与否*/
    if (false == NFCRC_s.N_flag.NFCRC_send_data_only)
    {
        NFCRC_s.N_flag.swipe_num = Rt_Swipe_Len();/*获取当前规定刷卡次数*/
        NFCRC_s.N_flag.swie_max_delms = NFCRC_s.N_flag.swipe_num * SWIPE_DELMS + SWIPE_DELMS_RES;/*计算最大超时时间*/
        NFCRC_s.N_flag.NFCRC_send_data_only = true;
        NFCRC_s.N_flag.swipe_stage = KEY_WAIT;/*第一次开始检测按键*/
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_ACTION_STATE, KEY_WAIT);/*显示当前测试状态为等待按键*/
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, REQUIRE_SWIPE_NUM, NFCRC_s.N_flag.swipe_num);/*显示规定刷卡次数*/
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_BUTTON_NUM, 0);/*显示按键次数0次*/
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_NUM, 0);/*显示刷卡次数0次*/
        Record_send_time = RTE_GET_TIMER();            /*记录发送开始时间*/
    }else if (true == NFCRC_s.N_flag.swipe_key_num_suc || RTE_TIMEOUT_JUDGMENT(Record_send_time, NFCRC_s.N_flag.swie_max_delms) )
    {

        if (true == NFCRC_s.N_flag.swipe_key_num_suc)/*刷卡次数正确*/
        {
            result = TEST_OK;
        }else{
            /*超时*/
            result = TEST_FAIL;
        }
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_ACTION_STATE, SWIPE_MX);/*显示当前测试状态为无需动作*/
        NFCRC_s.N_flag.swipe_stage = SWIPE_MX;
        NFCRC_s.N_flag.NFCRC_send_data_only = false;
                        /*测试完后，断开Q1，把产品供电电源断开*/
                RTE_GPIO_PIN_SET_LEVEL(GPIOE, QuieCur_CTRL_O_PE6_Pin, GPIO_PIN_RESET);
    }
    NFCRed_key();/*按键检测*/

    /*150ms获取一次刷卡情况*/
    if (SWIPE_WAIT == NFCRC_s.N_flag.swipe_stage)
    {
        if (false == NFCRC_s.N_flag.SWIPE_send_data_only/* condition */)
        {
            SWIPE_send_time = RTE_GET_TIMER();    // 记录开始检测刷卡的开始时间
            NFCRC_s.cantx_flag = OK_SENT_OR_RECEIVED;/*开始接收561的数据*/
            NFCRC_s.canrx_flag = NO_SENT_OR_RECEIVED;
            NFCRC_s.N_flag.SWIPE_send_data_only = true;
        }else if (RTE_TIMEOUT_JUDGMENT(SWIPE_send_time, SWIPE_DELMS) || OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag)
        {
            /* code */
            if (OK_SENT_OR_RECEIVED == NFCRC_s.canrx_flag && CAN_SWIPE_ID == NFCRC_s.canrx.can_id)
            {
                NFCRC_s.N_flag.swipe_stage = KEY_WAIT;
                RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_ACTION_STATE, KEY_WAIT);/*显示当前测试状态为等待刷卡*/
                NFCRC_s.N_flag.swipe_count ++;
                RTE_UART7_LCD_SHOW(NFC_READER_TEST, SWIPE_NUM, (uint32_t)NFCRC_s.N_flag.swipe_count);/*显示当前刷卡按键次数*/
                if (NFCRC_s.N_flag.swipe_num == NFCRC_s.N_flag.swipe_count && NFCRC_s.N_flag.swipe_num == NFCRC_s.N_flag.key_count) 
                {
                    NFCRC_s.N_flag.swipe_key_num_suc = true;/*刷卡次数正确*/
                }
                RTE_BUZZER_ALARM(1);/*成功刷卡一次响一声*/
            }else{
                /*超时*/
                result = TEST_FAIL;
                                /*测试完后，断开Q1，把产品供电电源断开*/
                RTE_GPIO_PIN_SET_LEVEL(GPIOE, QuieCur_CTRL_O_PE6_Pin, GPIO_PIN_RESET);
            }
            NFCRC_s.N_flag.SWIPE_send_data_only = false;
        }
    }
    
    return result;
}

/*
 * 函数介绍: 修改NFC读卡器测试阶段
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void Modify_NFCRC_testing_phase(NFC_Read_stage phase)
{
    NFCRC_s.stage = phase;
}

/*
 * 函数介绍: 在LCD上显示阶段结果
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void NFCRC_Stage_result_LCDshow(Rt_result result, NFC_Read_stage stage)
{
    if (TEST_WAIT == result)
    {
        return;
    }
    switch (stage)
    {
    case CAN_TEST:
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, CAN_COMMUNICATION, result);
        break;
    case LOW_TEST:
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, LOW_POWER_STATE, result);
        break;
    case CARD_TEST:
        RTE_UART7_LCD_SHOW(NFC_READER_TEST, CARD_SWIPE_TEST, result);
        break;
    default:
        break;
    }
}

/*
 * 函数介绍: 阶段结果判断
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void NFCRC_Stage_result_judgment(Rt_result result, NFC_Read_stage stage)
{
    stage += 1;
    NFCRC_Stage_result_LCDshow(result,NFCRC_s.stage);
    if (TEST_OK == result) /*该阶段通讯测试通过*/
    {
        if (CARD_TEST == NFCRC_s.stage)
        {
            NFCRC_s.RC_results = TEST_OK ;/*测试项流程已走完*/
        }
        NFCRC_s.e_sta[NFCRC_s.stage] = result;
        /*修改EHBL的测试阶段为下一个阶段*/
        Modify_NFCRC_testing_phase(stage);
    }
    else if (TEST_FAIL == result)
    {
        if (CARD_TEST == NFCRC_s.stage)
        {
            NFCRC_s.RC_results = TEST_OK ;/*测试项流程已走完*/
        }
        NFCRC_s.e_sta[NFCRC_s.stage] = result;
        /*修改EHBL的测试阶段为下一个阶段*/
        Modify_NFCRC_testing_phase(stage);
    }
    else
    {
    }
}

/*
 * 函数介绍: NFC读卡器测试结果展示
 * 参数:
 * 返回值: {*}
 * 备注:
 * 11.若所有测试项结果OK，测试合格指示绿灯亮，蜂鸣器响1声，
 * LCD屏显示测试合格，并向打标机发送打标信号
 * 反之，测试不合格指示红灯亮，蜂鸣器响3声，
 * LCD屏显示测试不合格。
 * （注： 不合格后进入下一个产品测试时需按一下不良次品盒的开关）
 */
Rt_result NFCRC_test_results(void)
{
    uint8_t i = 0;
    Rt_result result = TEST_WAIT; /*测试结果值*/
    /*判断测试流程是否走完*/
    if (TEST_OK == NFCRC_s.RC_results)
    {
        result = TEST_OK;
        NFCRC_s.RC_results = TEST_WAIT; /*置回标志*/
        for (i = 0; i < NFC_READ_MAX; i++)
        {
            result |= NFCRC_s.e_sta[i];
        }
        result |= NFCRC_s.RED_ver_comp;
    }
    else
    {
    }
    return result;
}

/*
 * 函数介绍: NFC读卡器功能测试
 * 参数:
 * 返回值: {*}
 * 备注:
 */
Rt_result NFCread_card_test(void)
{
    Rt_result result = TEST_WAIT; /*返回值*/
	if(NFC_READ_MAX > NFCRC_s.stage)
    {
        result = NFC_read[NFCRC_s.stage].NFC_read_test();
    }
    NFCRC_Stage_result_judgment(result, NFCRC_s.stage);/*判断当前测试项是否测试通过或失败*/
    result = NFCRC_test_results();/*判断当前测试得读卡器是否测试通过*/
    return result;
}
